package com.ruoyi.jihuo.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.jihuo.config.TaskManager;
import com.ruoyi.jihuo.domain.*;
import com.ruoyi.jihuo.enums.JhTmTaskStatus;
import com.ruoyi.jihuo.mapper.JhTmTaskMapper;
import com.ruoyi.jihuo.service.*;
import com.ruoyi.jihuo.service.handler.BatchProcessor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

/**
 * 发布天猫任务Service业务层处理
 *
 * @author ruoyi
 * @date 2025-03-27
 */
@Slf4j
@Service
public class JhTmTaskServiceImpl implements IJhTmTaskService {
    @Autowired
    private JhTmTaskMapper jhTmTaskMapper;

    @Autowired
    private BatchProcessor batchProcessor;

    @Autowired
    private IJhTmUploadDataService jhTmUploadDataService;

    @Autowired
    private IJhTmGoodsService jhTmGoodsService;

    @Autowired
    private IJhTmTemplateService jhTmTemplateService;

    @Autowired
    private IJhTmAccountService jhTmAccountService;

    @Autowired
    private IJhTmProductsOnSaleService jhTmProductsOnSaleService;

    @Autowired
    private TaskManager taskManager;

    @Autowired
    private RedisCache redisCache;

    /**
     * 查询发布天猫任务
     *
     * @param jhId 发布天猫任务主键
     * @return 发布天猫任务
     */
    @Override
    public JhTmTask selectJhTmTaskByJhId(Long jhId) {
        return jhTmTaskMapper.selectJhTmTaskByJhId(jhId);
    }

    /**
     * 查询发布天猫任务列表
     *
     * @param jhTmTask 发布天猫任务
     * @return 发布天猫任务
     */
    @Override
    public List<JhTmTask> selectJhTmTaskList(JhTmTask jhTmTask) {
        jhTmTask.setJhUserId(SecurityUtils.getUserId());
        return jhTmTaskMapper.selectJhTmTaskList(jhTmTask);
    }

    /**
     * 新增发布天猫任务
     *
     * @param jhTmTask 发布天猫任务
     * @return 结果
     */
    @Override
    public int insertJhTmTask(JhTmTask jhTmTask) {
        jhTmTask.setJhStatus(JhTmTaskStatus.WAITING.toString());
        jhTmTask.setJhUserId(SecurityUtils.getUserId());
        return jhTmTaskMapper.insert(jhTmTask);
    }

    /**
     * 修改发布天猫任务
     *
     * @param jhTmTask 发布天猫任务
     * @return 结果
     */
    @Override
    public int updateJhTmTask(JhTmTask jhTmTask) {
        return jhTmTaskMapper.updateJhTmTask(jhTmTask);
    }

    /**
     * 批量删除发布天猫任务
     *
     * @param jhIds 需要删除的发布天猫任务主键
     * @return 结果
     */
    @Override
    public int deleteJhTmTaskByJhIds(String[] jhIds) {
        return jhTmTaskMapper.deleteJhTmTaskByJhIds(jhIds);
    }

    /**
     * 删除发布天猫任务信息
     *
     * @param jhId 发布天猫任务主键
     * @return 结果
     */
    @Override
    public int deleteJhTmTaskByJhId(String jhId) {
        return jhTmTaskMapper.deleteJhTmTaskByJhId(jhId);
    }

    @Override
    public void start(Long jhId) {
        JhTmTask jhTmTask = jhTmTaskMapper.selectJhTmTaskByJhId(jhId);
        Long jhDataId = jhTmTask.getJhDataId();
        JhTmTemplate template = jhTmTemplateService.selectJhTmTemplateByJhId(jhTmTask.getJhTemplateId());
        // todo 需要根据模板进行过滤转换值
        List<JhTmGoods> jhTmGoods = jhTmGoodsService.selectJhTmGoodsListByPackageId(jhDataId);
        JhTmAccount jhTmAccount = jhTmAccountService.selectJhTmAccountByJhId(jhTmTask.getJhTmId());
        jhTmTask.setJhStatus(JhTmTaskStatus.PROCESSING.toString());
        jhTmTaskMapper.updateById(jhTmTask);

        List<JSONObject> dataList = new ArrayList<>();
        int index = 0;
        for (JhTmGoods jhTmGood : jhTmGoods) {
            index++;
            // 构建待插入的在售商品对象
            JhTmProductsOnSale jhTmProductsOnSale = buildProductsOnsale(jhId, jhTmGood, jhTmTask.getJhTmId(), jhDataId);
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("jsonId", index);
            jsonObject.put("item", jhTmGood);
            jsonObject.put("tmAccount", jhTmAccount);
            jsonObject.put("template", template);
            jsonObject.put("productsOnSale", jhTmProductsOnSale);
            dataList.add(jsonObject);
        }
        processDataList(jhTmTask.getJhId(), dataList, jhTmTask,"add");
    }

    /**
     * 重新上架任务  只会上架这批上架失败的，和未上架的商品
     * @param jhId
     * @return
     */
    @Override
    public void againStart(Long jhId) {
        JhTmTask jhTmTask = jhTmTaskMapper.selectJhTmTaskByJhId(jhId);
        Long jhDataId = jhTmTask.getJhDataId();
        JhTmTemplate template = jhTmTemplateService.selectJhTmTemplateByJhId(jhTmTask.getJhTemplateId());
        // todo 需要根据模板进行过滤转换值
        List<JhTmGoods> jhTmGoods = jhTmGoodsService.selectJhTmGoodsListByPackageId(jhDataId);
        JhTmAccount jhTmAccount = jhTmAccountService.selectJhTmAccountByJhId(jhTmTask.getJhTmId());
        jhTmTask.setJhStatus(JhTmTaskStatus.PROCESSING.toString());
        jhTmTask.setJhFailNum(0);
        jhTmTaskMapper.updateById(jhTmTask);
        //获取这笔任务上架失败的
        Map<Long,JhTmProductsOnSale> productsOnSaleMap = jhTmProductsOnSaleService.selectMapByTaskIdAndStatus(jhId,"3");
        List<JSONObject> dataList = new ArrayList<>();
        int index = 0;
        for (JhTmGoods jhTmGood : jhTmGoods) {
            index++;
            // 如果上架失败中不存在，代表是这个任务中未上架的
            JhTmProductsOnSale jhTmProductsOnSale = productsOnSaleMap.getOrDefault(jhTmGood.getJhId(),buildProductsOnsale(jhId, jhTmGood, jhTmTask.getJhTmId(), jhDataId));

            JSONObject jsonObject = new JSONObject();
            jsonObject.put("jsonId", index);
            jsonObject.put("item", jhTmGood);
            jsonObject.put("tmAccount", jhTmAccount);
            jsonObject.put("template", template);
            jsonObject.put("productsOnSale", jhTmProductsOnSale);
            dataList.add(jsonObject);
        }
        processDataList(jhTmTask.getJhId(), dataList, jhTmTask,"update");
    }

    private static JhTmProductsOnSale buildProductsOnsale(Long jhId, JhTmGoods jhTmGood, Long jhTmId, Long jhDataId) {
        JhTmProductsOnSale jhTmProductsOnSale = new JhTmProductsOnSale();
        jhTmProductsOnSale.setJhName(jhTmGood.getJhTitle());
        jhTmProductsOnSale.setJhClass(jhTmGood.getJhCategoryId());
        jhTmProductsOnSale.setJhTmAccountId(jhTmId);
        jhTmProductsOnSale.setJhStatus("0");
        jhTmProductsOnSale.setJhGoodId(jhTmGood.getJhId());
        jhTmProductsOnSale.setJhTaskId(jhId);
        jhTmProductsOnSale.setJhOriginalUrl(jhTmGood.getJhOriginalUrl());
        jhTmProductsOnSale.setJhDataPackageId(jhDataId);
        return jhTmProductsOnSale;
    }
    private void processDataList(Long taskId, List<JSONObject> dataList, JhTmTask jhTmTask, String operationType) {
        //注册异步任务
        taskManager.registerTask(taskId.toString());
        //记录任务处理进度
        redisCache.setCacheMapValue((CacheConstants.TASK_PROGRESS+"-"+taskId), "total", dataList.size());
        CompletableFuture<List<JhTmProductsOnSale>> future =batchProcessor.processBatch(dataList, taskId.toString());
        //异步方法执行完毕后，执行后续操作
        future.whenComplete((productsOnSales, error) -> {
            try {
                // 保存已处理的商品
                try {
                    if ("add".equals(operationType)) {
                        jhTmProductsOnSaleService.insertJhTmProductsOnSaleBatch(productsOnSales);
                    }else if ("update".equals(operationType)) {
                        jhTmProductsOnSaleService.updateBatch(productsOnSales);
                    }
                }catch (Exception e){
                    log.error("{}已处理的商品失败", operationType, e);
                }
                // 成功/失败/过滤
                long filteredCount = productsOnSales.stream()
                        .filter(p -> "1".equals(p.getJhStatus())).count();
                long successCount = productsOnSales.stream()
                        .filter(p -> "2".equals(p.getJhStatus())).count();
                long failedCount = productsOnSales.stream()
                        .filter(p -> "3".equals(p.getJhStatus())).count();

                jhTmTask.setJhFiltrationNum((int) filteredCount);
                jhTmTask.setJhSuccessNum((int) successCount);
                jhTmTask.setJhFailNum((int) failedCount);
                //如果任务取消 就更新任务状态为取消，否则更新为完成或失败
                if (taskManager.isCancelled(taskId.toString())) {
                    jhTmTask.setJhStatus(JhTmTaskStatus.CANCEL.toString());
                } else {
                    jhTmTask.setJhStatus(failedCount == productsOnSales.size()
                            ? JhTmTaskStatus.FAILED.toString()
                            : JhTmTaskStatus.COMPLETED.toString());
                }

            } finally {
                taskManager.removeTask(taskId.toString());
                jhTmTaskMapper.updateById(jhTmTask);
            }
        });
    }

    @Override
    public void updateJhStatus(String taskId, String string) {
        JhTmTask jhTmTask = jhTmTaskMapper.selectById(taskId);
        jhTmTask.setJhStatus(string);
        jhTmTaskMapper.updateById(jhTmTask);
    }
}
